package com.codinghero.example.bcel;

import static org.apache.bcel.Constants.ACC_PUBLIC;
import static org.apache.bcel.Constants.ACC_STATIC;
import static org.apache.bcel.Constants.ACC_SUPER;
import static org.apache.bcel.Constants.GETSTATIC;
import static org.apache.bcel.Constants.INVOKEVIRTUAL;

import java.io.IOException;

import org.apache.bcel.generic.ArrayType;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
import org.apache.bcel.util.JavaWrapper;

public class BCELHelloWorld {

	public static void main(String[] args) {
		ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object",
				"<generated>", ACC_PUBLIC | ACC_SUPER, null);
		
		
		ConstantPoolGen cp = cg.getConstantPool();
		InstructionList il = new InstructionList();
		
		
		MethodGen mg = new MethodGen(ACC_STATIC | ACC_PUBLIC, Type.VOID,
				new Type[] { new ArrayType(Type.STRING, 1) },
				new String[] { "args" }, "main", "HelloWorld", il, cp);
		
		
		InstructionFactory factory = new InstructionFactory(cg);
		
		
		ObjectType printStream = new ObjectType("java.io.PrintStream");
		il.append(factory.createFieldAccess("java.lang.System", "out", printStream, GETSTATIC));
		il.append(new PUSH(cp, "Hello World!"));
		il.append(factory.createInvoke("java.io.PrintStream", "println",
				Type.VOID, new Type[] { Type.STRING }, INVOKEVIRTUAL));
		il.append(InstructionConstants.RETURN);
		
		
		mg.setMaxStack();
		cg.addMethod(mg.getMethod());
		il.dispose();
		cg.addEmptyConstructor(ACC_PUBLIC);
		
		
		try {
			cg.getJavaClass().dump("E:\\WorkSpace_OSGi\\LiuTongUtils\\target\\classes\\HelloWorld.class");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		try {
			new JavaWrapper().runMain("HelloWorld", new String[]{});
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}
